package com.uade.empresasdistribuidas.model;

import java.sql.Date;
import java.util.Calendar;
import java.util.List;

import com.uade.empresasdistribuidas.connection.HibernateUtil;
import com.uade.empresasdistribuidas.dao.EnvioLocalDAO;
import com.uade.empresasdistribuidas.dao.EnvioLocalDAOImpl;
import com.uade.empresasdistribuidas.entities.EnvioLocalDTO;
import com.uade.empresasdistribuidas.entities.PedidoDTO;
import com.uade.empresasdistribuidas.entities.PedidoLocalDTO;


public class EnvioLocal {
	private EnvioLocalDTO envioDTO;
	private static EnvioLocalDAO envioDAO;
	private Recorrido recorrido;
	private Vehiculo vehiculo;
	public static final String EN_DEPOSITO="EN_DEPOSITO";
	public static final String EN_TRAYECTO = "EN_TRAYECTO";
	private static final String ENTREGADO = "ENTREGADO";
	
	public EnvioLocal(String sucursalNombreInicio,String sucursalNombreFin, Float peso,boolean refrigeracion,Date maximaLlegada) throws Exception{
		recorrido=new Recorrido(sucursalNombreInicio,sucursalNombreFin);
		envioDTO=new EnvioLocalDTO();
		envioDTO.setEstado(EN_DEPOSITO);
		envioDTO.setFechaMaximaLlegada(maximaLlegada);
		envioDTO.setRecorrido(recorrido.getRecorrido());
		vehiculo=Vehiculo.obtenerVehiculoLibre(sucursalNombreInicio,peso,recorrido.obtenerLocalidadOrigen(),refrigeracion);
		if (vehiculo==null){
			throw new Exception();
		}
		envioDTO.setVehiculo(vehiculo.getVehiculo());
	}
	
	
	public EnvioLocal(EnvioLocalDTO envio) {
		envioDTO=envio;
	}
	
	public static EnvioLocal obtenerEnvioEnEspera(String sucursalNombreInicio, String sucursalNombreFin, Float pesoPedido,boolean refrigerado){
		Recorrido recorrido=new Recorrido(sucursalNombreInicio,sucursalNombreFin);
		List<EnvioLocalDTO> envios=getEnvioDAO().obtenerEnviosEnEsperaMismoTrayectoMismosObjetos(recorrido.getRecorrido().getCodigoRecorrido(),refrigerado);
		EnvioLocal envioLocal=null;
		for (EnvioLocalDTO envio: envios){
			envioLocal=new EnvioLocal(envio);
			if (envioLocal.entraEnvio(pesoPedido)){
				envioLocal.setVehiculo(new Vehiculo(envio.getVehiculo()));
				break;
			}else{
				//este envio no nos sirve
				envioLocal=null;
			}
		}
		return envioLocal;
	}

	private boolean entraEnvio(Float pesoPedido) {
		return envioDTO.hayEspacio(pesoPedido);
		
	}


	public static EnvioLocalDAO getEnvioDAO(){
		if (envioDAO==null){
			envioDAO= new EnvioLocalDAOImpl();
			envioDAO.setSession((HibernateUtil.getSession()));
		}
		return envioDAO;
		
	}


	public void persistirEnvio() {
		envioDTO=getEnvioDAO().makePersistent(envioDTO);
		
	}


	public EnvioLocalDTO getEnvioDTO() {
		return envioDTO;
	}


	public void setEnvioDTO(EnvioLocalDTO envioDTO) {
		this.envioDTO = envioDTO;
	}


	public void asignarVehiculo() {
		vehiculo.asignarVehiculo();
		
	}


	public void procesarSalida() {
		if (validarSalida()){
			envioDTO.setEstado(EN_TRAYECTO);
			// el vehiculo va a salir en una hora
			envioDTO.setFechaPartida(new Date(Calendar.getInstance().getTimeInMillis()+(1000*60*60)));
			vehiculo.cambiarEstado(Vehiculo.EN_TRANSITO);
			for (PedidoDTO pedido:envioDTO.getPedidos()){
				PedidoLocal pedidoLocal=new PedidoLocal(pedido);
				pedidoLocal.cambiarEstado();
			}
			getEnvioDAO().makePersistent(envioDTO);
		}
		
	}


	private boolean validarSalida() {
		return envioDTO.puedeSalir() && envioDTO.estaEnSucursalVehiculo();
	}


	public Vehiculo getVehiculo() {
		return vehiculo;
	}


	public void setVehiculo(Vehiculo vehiculo) {
		this.vehiculo = vehiculo;
	}


	public static EnvioLocal buscarEnvioEnEspera(Integer nroVehiculo, String sucursalNombre) {
		EnvioLocal envioLocal=null;
		EnvioLocalDTO envio=getEnvioDAO().obtenerEnvioEnEspera(nroVehiculo,sucursalNombre);
		if (envio!=null){
			envioLocal=new EnvioLocal(envio);
			envioLocal.setVehiculo(new Vehiculo(envio.getVehiculo()));
		}
		return envioLocal;
		
	}


	public static EnvioLocal buscarEnvioEnTrayecto(Integer nroVehiculo,
			String sucursal) {
		EnvioLocal envioLocal=null;
		EnvioLocalDTO envio=getEnvioDAO().obtenerEnvioEnTrayecto(nroVehiculo,sucursal);
		if (envio!=null){
			envioLocal=new EnvioLocal(envio);
			envioLocal.setVehiculo(new Vehiculo(envio.getVehiculo()));
		}
		return envioLocal;
	}


	public void procesarLlegada() {
		envioDTO.setEstado(ENTREGADO);
		// el vehiculo va a salir en una hora
		envioDTO.setFechaLlegada(new Date(Calendar.getInstance().getTimeInMillis()));
		vehiculo.entregarEnvio(envioDTO.getRecorrido().getDistancia());
		for (PedidoDTO pedido:envioDTO.getPedidos()){
			PedidoLocal pedidoLocal=new PedidoLocal(pedido);
			pedidoLocal.cambiarEstado();
		}
		getEnvioDAO().makePersistent(envioDTO);	
	}





	public void agregarPedido(PedidoDTO pedido) {
		envioDTO.addPedido(pedido);
		
	}
}
